<template>
  <div class="message" :class="message.role">
    <div class="message-avatar">
      {{ message.role === 'user' ? '我' : 'AI' }}
    </div>
    <div class="message-content">
      <!-- 思考过程 -->
      <div v-if="displayThinkingContent" class="thinking-section">
        <div class="thinking-header">
          <span class="thinking-icon">💭</span>
          <span>思考过程</span>
          <span v-if="message.isStreaming && isInThinkingPhase" class="thinking-status">正在思考...</span>
        </div>
        <div class="thinking-content" v-html="displayThinkingContent"></div>
      </div>
      
      <!-- 实际回答 -->
      <div v-if="displayActualContent" class="message-text" v-html="displayActualContent"></div>
      
      <!-- 流式输入指示器 -->
      <div v-if="message.isStreaming && !isInThinkingPhase" class="streaming-indicator">
        <span class="typing-cursor">|</span>
      </div>
      
      <!-- 消息元数据 -->
      <div class="message-metadata" v-if="messageMetadata">
        <span class="model-info" v-if="messageMetadata.model">
          {{ messageMetadata.model }}
        </span>
        <span class="thread-info" v-if="messageMetadata.threadId">
          Thread: {{ messageMetadata.threadId }}
        </span>
        <span class="temperature-info" v-if="messageMetadata.temperature !== null">
          Temp: {{ messageMetadata.temperature }}
        </span>
        <span class="step-info" v-if="messageMetadata.step">
          Step: {{ messageMetadata.step }}
        </span>
      </div>
      
      <div class="message-time">{{ formatTime(message.timestamp) }}</div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'

const props = defineProps({
  message: {
    type: Object,
    required: true
  },
  enableTypewriter: {
    type: Boolean,
    default: false // 默认关闭打字机效果，因为现在是实时流式显示
  },
  typewriterSpeed: {
    type: Number,
    default: 30 // 毫秒
  }
})

// 打字机效果相关状态
const displayThinkingContent = ref('')
const displayActualContent = ref('')
const isTyping = ref(false)
const typewriterTimer = ref(null)

// 检测是否在思考阶段
const isInThinkingPhase = computed(() => {
  return props.message.isStreaming && props.message.thinkingContent && !props.message.actualContent
})

// 处理思考内容
const processedThinkingContent = computed(() => {
  if (!props.message.thinkingContent) return ''
  
  // 移除可能残留的标签
  let content = props.message.thinkingContent.replace(/<\/?think>/gi, '').trim()
  return content
})

// 处理实际内容
const processedActualContent = computed(() => {
  // 对于用户消息，使用 content 字段
  if (props.message.role === 'user') {
    return props.message.content || ''
  }
  
  // 对于AI消息，使用 actualContent 字段
  if (!props.message.actualContent) return ''
  
  // 移除可能残留的标签
  let content = props.message.actualContent.replace(/<\/?think>/gi, '').trim()
  return content
})

// 格式化内容（支持markdown）
const formatContent = (content) => {
  if (!content) return ''
  
  // 转义HTML
  let formatted = content.replace(/&/g, '&amp;')
                        .replace(/</g, '&lt;')
                        .replace(/>/g, '&gt;')
  
  // 简单的markdown支持
  formatted = formatted.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>') // 粗体
  formatted = formatted.replace(/\*(.*?)\*/g, '<em>$1</em>') // 斜体
  formatted = formatted.replace(/`(.*?)`/g, '<code>$1</code>') // 行内代码
  formatted = formatted.replace(/\n/g, '<br>') // 换行
  
  return formatted
}

// 打字机效果实现
const startTypewriter = () => {
  if (!props.enableTypewriter || props.message.isStreaming) {
    // 如果不启用打字机效果或正在流式传输，直接显示内容
    displayThinkingContent.value = formatContent(processedThinkingContent.value)
    displayActualContent.value = formatContent(processedActualContent.value)
    return
  }

  const thinkingText = processedThinkingContent.value
  const actualText = processedActualContent.value
  
  let thinkingIndex = 0
  let actualIndex = 0
  let currentPhase = 'thinking' // 'thinking' | 'actual'
  
  isTyping.value = true
  displayThinkingContent.value = ''
  displayActualContent.value = ''
  
  const typeNextChar = () => {
    if (currentPhase === 'thinking' && thinkingText) {
      if (thinkingIndex < thinkingText.length) {
        displayThinkingContent.value = formatContent(thinkingText.substring(0, thinkingIndex + 1))
        thinkingIndex++
        typewriterTimer.value = setTimeout(typeNextChar, props.typewriterSpeed)
      } else {
        currentPhase = 'actual'
        typewriterTimer.value = setTimeout(typeNextChar, props.typewriterSpeed * 2) // 稍微停顿
      }
    } else if (currentPhase === 'actual' && actualText) {
      if (actualIndex < actualText.length) {
        displayActualContent.value = formatContent(actualText.substring(0, actualIndex + 1))
        actualIndex++
        typewriterTimer.value = setTimeout(typeNextChar, props.typewriterSpeed)
      } else {
        isTyping.value = false
      }
    } else {
      // 如果没有思考内容，直接显示实际内容
      if (!thinkingText && actualText) {
        currentPhase = 'actual'
        if (actualIndex < actualText.length) {
          displayActualContent.value = formatContent(actualText.substring(0, actualIndex + 1))
          actualIndex++
          typewriterTimer.value = setTimeout(typeNextChar, props.typewriterSpeed)
        } else {
          isTyping.value = false
        }
      } else {
        isTyping.value = false
      }
    }
  }
  
  typeNextChar()
}

// 停止打字机效果
const stopTypewriter = () => {
  if (typewriterTimer.value) {
    clearTimeout(typewriterTimer.value)
    typewriterTimer.value = null
  }
  isTyping.value = false
}

// 实时更新显示内容（用于流式传输）
const updateDisplayContent = () => {
  if (props.message.isStreaming || !props.enableTypewriter) {
    // 流式传输时实时显示
    displayThinkingContent.value = formatContent(processedThinkingContent.value)
    displayActualContent.value = formatContent(processedActualContent.value)
  } else {
    // 非流式时使用打字机效果
    stopTypewriter()
    startTypewriter()
  }
}

// 提取元数据信息
const messageMetadata = computed(() => {
  // 优先使用新的 metadata 字段
  if (props.message.metadata) {
    return {
      model: props.message.metadata.model || null,
      threadId: props.message.metadata.threadId || null,
      temperature: props.message.metadata.temperature !== undefined ? props.message.metadata.temperature : null,
      step: props.message.metadata.step || null,
      node: props.message.metadata.node || null,
      provider: props.message.metadata.provider || null
    }
  }

  // 兼容旧格式
  const content = props.message.content
  if (typeof content === 'string') {
    try {
      // 尝试从JSON格式中提取元数据
      const jsonData = JSON.parse(content)
      if (jsonData.metadata) {
        return {
          model: jsonData.metadata.model || null,
          threadId: jsonData.metadata.threadId || null,
          temperature: jsonData.metadata.temperature !== undefined ? jsonData.metadata.temperature : null,
          step: jsonData.metadata.step || null,
          node: jsonData.metadata.node || null,
          provider: jsonData.metadata.provider || null
        }
      }
    } catch (e) {
      // 如果不是JSON，尝试从旧格式中提取
      if (content.includes('AIMessageChunk')) {
        try {
          const modelMatch = content.match(/'ls_model_name': '([^']*)'/)
          const threadMatch = content.match(/'thread_id': '([^']*)'/)
          const tempMatch = content.match(/'ls_temperature': ([^,}]*)[,}]/)
          
          if (modelMatch || threadMatch) {
            return {
              model: modelMatch ? modelMatch[1] : null,
              threadId: threadMatch ? threadMatch[1] : null,
              temperature: tempMatch ? parseFloat(tempMatch[1]) : null,
              step: null,
              node: null,
              provider: null
            }
          }
        } catch (err) {
          console.warn('解析元数据失败:', err)
        }
      }
    }
  }
  return null
})

// 格式化时间
const formatTime = (timestamp) => {
  if (!timestamp) return ''
  
  const date = new Date(timestamp)
  const now = new Date()
  const diff = now - date
  
  if (diff < 60000) {
    return '刚刚'
  } else if (diff < 3600000) {
    return `${Math.floor(diff / 60000)}分钟前`
  } else if (diff < 86400000) {
    return `${Math.floor(diff / 3600000)}小时前`
  } else {
    return date.toLocaleString('zh-CN', {
      month: 'short',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit'
    })
  }
}

// 监听消息内容变化
watch(() => [
  props.message.thinkingContent, 
  props.message.actualContent, 
  props.message.isStreaming
], () => {
  updateDisplayContent()
}, { immediate: true })

// 组件挂载时初始化显示
onMounted(() => {
  updateDisplayContent()
})

// 组件卸载时清理定时器
onUnmounted(() => {
  stopTypewriter()
})
</script>

<style scoped>
.message {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 10px 15px;
  max-width: 100%;
  width: 100%;
  margin-bottom: 5px;
}

.message.user {
  flex-direction: row-reverse;
  background: transparent;
  justify-content: flex-start;
  margin-left: auto;
  margin-right: 0;
}

.message.assistant {
  background: transparent;
  justify-content: flex-start;
  margin-right: auto;
  margin-left: 0;
}

.message-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  color: white;
  flex-shrink: 0;
  font-size: 12px;
}

.message.user .message-avatar {
  background: linear-gradient(135deg, #007bff 0%, #0056b3 100%);
}

.message.assistant .message-avatar {
  background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
}

.message-content {
  display: block;
  min-width: 120px;
  max-width: calc(80% - 50px);
  background: rgba(79, 172, 254, 0.1);
  padding: 10px;
  border: 1px solid rgba(79, 172, 254, 0.2);
  width: auto;
  border-radius: 12px;
  position: relative;
  flex-shrink: 1;
  word-wrap: break-word;
  white-space: normal;
}

.message.user .message-content {
  background: rgba(0, 123, 255, 0.1);
  border: 1px solid rgba(0, 123, 255, 0.2);
  margin-left: auto;
}

.message.assistant .message-content {
  margin-right: auto;
}

/* AI消息靠左对齐，完整容器靠左 */
.message.assistant {
  justify-content: flex-start;
  width: fit-content;
  max-width: 80%;
}

.message.assistant .message-content {
  margin-left: 0;
  margin-right: auto;
}

/* 用户消息靠右对齐，完整容器靠右 */
.message.user {
  justify-content: flex-start;
  width: fit-content;
  max-width: 80%;
  margin-left: auto;
  margin-right: 0;
}

.message.user .message-content {
  margin-right: 0;
  margin-left: auto;
}

.message-text {
  word-break: break-word;
  word-wrap: break-word;
  white-space: normal;
  line-height: 1.5;
  color: #333;
  font-size: 0.95em;
  display: block;
}

.message-text :deep(code) {
  background: rgba(0, 0, 0, 0.1);
  padding: 2px 6px;
  border-radius: 4px;
  font-family: 'Courier New', monospace;
  font-size: 0.9em;
}

.message-text :deep(strong) {
  font-weight: 600;
}

.message-text :deep(em) {
  font-style: italic;
}

/* 思考过程样式 */
.thinking-section {
  background: rgba(255, 193, 7, 0.08);
  border: 1px solid rgba(255, 193, 7, 0.2);
  border-radius: 8px;
  padding: 10px;
  margin-bottom: 10px;
  position: relative;
}

.thinking-header {
  font-size: 12px;
  font-weight: 600;
  color: #856404;
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.thinking-icon {
  font-size: 14px;
}

.thinking-status {
  font-size: 11px;
  color: #6c5ce7;
  font-weight: normal;
  font-style: italic;
  margin-left: auto;
}

.thinking-content {
  font-size: 12px;
  color: #6c5ce7;
  line-height: 1.4;
  font-style: italic;
  word-break: break-word;
  word-wrap: break-word;
  white-space: normal;
  display: block;
}

.thinking-content :deep(code) {
  background: rgba(255, 193, 7, 0.15);
  padding: 2px 4px;
  border-radius: 4px;
  font-family: 'Courier New', monospace;
  font-size: 0.9em;
}

.thinking-content :deep(strong) {
  font-weight: 600;
}

.thinking-content :deep(em) {
  font-style: italic;
}

/* 流式输入指示器 */
.streaming-indicator {
  margin-top: 8px;
}

.typing-cursor {
  display: inline-block;
  animation: blink 1s infinite;
  font-weight: bold;
  color: #007bff;
  font-size: 16px;
}

@keyframes blink {
  0%, 50% { opacity: 1; }
  51%, 100% { opacity: 0; }
}

/* 元数据样式 */
.message-metadata {
  margin-top: 8px;
  font-size: 10px;
  opacity: 0.7;
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.model-info {
  background: rgba(0, 123, 255, 0.1);
  color: #007bff;
  padding: 2px 8px;
  border-radius: 12px;
  font-weight: 500;
}

.thread-info {
  background: rgba(108, 117, 125, 0.1);
  color: #6c757d;
  padding: 2px 8px;
  border-radius: 12px;
  font-family: monospace;
  font-size: 9px;
  white-space: nowrap;
  overflow: visible;
  text-overflow: initial;
}

.temperature-info {
  background: rgba(255, 193, 7, 0.1);
  color: #856404;
  padding: 2px 8px;
  border-radius: 12px;
  font-weight: 500;
}

.step-info {
  background: rgba(40, 167, 69, 0.1);
  color: #28a745;
  padding: 2px 8px;
  border-radius: 12px;
  font-weight: 500;
}

.message-time {
  font-size: 11px;
  opacity: 0.6;
  margin-top: 8px;
  color: #6c757d;
}

.message.user .message-time {
  text-align: right;
}

.message.user .message-metadata {
  justify-content: flex-end;
}

/* 用户消息的思考过程样式调整 */
.message.user .thinking-section {
  background: rgba(0, 123, 255, 0.08);
  border-color: rgba(0, 123, 255, 0.2);
}

.message.user .thinking-header {
  color: #004085;
}

.message.user .thinking-content {
  color: #495057;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .message {
    padding: 12px 16px;
    gap: 10px;
  }
  
  .message-avatar {
    width: 36px;
    height: 36px;
    font-size: 12px;
  }
  
  .thinking-section {
    padding: 12px;
    margin-bottom: 12px;
  }
  
  .message-metadata {
    gap: 6px;
  }
  
  .model-info,
  .thread-info,
  .temperature-info,
  .step-info {
    padding: 1px 6px;
    font-size: 8px;
  }
}
</style>